package Biblioteca

import Contas.Administrador 
import Contas.Projeto 
import Contas.Usuario 
import org.springframework.security.ui.webapp.AuthenticationProcessingFilter 

class LivroController {
	
	static livroResult
	static consulta
	
	static allowedMethods = [save: "POST", update: "POST", delete: "POST"]
	
	def fornecedores = Projeto.executeQuery("select nome from Projeto")
	
	def index = {		 
		redirect(action: "list", params: params)
	}
	
	private String getTipoUsuario (){
		def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
		Usuario user = Contas.Usuario.findByUsername(username)
		def tipo
		if (Administrador.get(user.id)==null){
			tipo = "Usuario"
		}else{
			tipo = "Admin"
		}
	return tipo
	}
	
	def list = {		
		params.max = Math.min(params.max ? params.int('max') : 10, 100)
		[livroInstanceList: Livro.list(params), livroInstanceTotal: Livro.count(), tipo:this.getTipoUsuario ()]
	}
	
	def reservar = {
		def livroInstance = Livro.get(params.id)
		def qtde = Exemplar.executeQuery("select id from Exemplar where isbnItem = " + livroInstance.isbn)
		def emprestados = Emprestimo.executeQuery("select dataDevolucao from Emprestimo where idItem = " + livroInstance.id+" and tipo = 'livro'")
		def reservados = Reserva.executeQuery("select id from Reserva where idItem = " + livroInstance.id)
		def jatemEmprestimo = false
		
		def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
		def dataHoje = new Date()
		def reservaInstance = new Reserva()
		reservaInstance.idItem = Integer.parseInt (params.id)
		reservaInstance.dataReserva = dataHoje
		reservaInstance.username = username.toString()
		reservaInstance.titulo = livroInstance.titulo
		reservaInstance.tipo = 'livro'
		
		def emprestimos_usuario = Emprestimo.executeQuery("select id from Emprestimo where login = " + "'" + username.toString() + "'")
		def reservas_usuario = Reserva.executeQuery("select idItem from Reserva where username = " + "'" + username.toString() +"'" )
		
		
		for (emprestimo in emprestimos_usuario){
			def livro_emprestimo = Emprestimo.executeQuery("select idItem from Emprestimo where idItem = " + emprestimo + " and tipo='livro'")
			if (livro_emprestimo.contains (livroInstance.id)){
				flash.message = "Voce ja possui um emprestimo deste livro."
				jatemEmprestimo = true
			}
		}
		if (reservas_usuario.contains(livroInstance.id)){
			flash.message = "Voce ja possui uma reserva deste livro."
		}else if (!jatemEmprestimo && (qtde.size() - emprestados.size() - reservados.size()) > 0){
			reservaInstance.save()
			flash.message = "${message(code: 'Livro Reservado com sucesso!', args: [message(code: 'Livro Reservado com sucesso!', default: 'Livro Reservado com sucesso!'), params.id])}"
			
		}else if (!jatemEmprestimo){
			flash.message = "Nao existe nenhum exemplar disponivel para este Livro."
			
		}
		redirect(action: "show", id: params.id)
		
	}
	
	def create = {
		def livroInstance = new Livro()
		def exemplarInstance = new Exemplar()
		livroInstance.properties = params

		if (!fornecedores.contains('Doacao')){
			fornecedores.add('Doacao')
		}

		return [livroInstance: livroInstance, exemplarInstance: exemplarInstance, fornecedores:fornecedores, tipo:this.getTipoUsuario ()]
	}
	
	def search = {
		return [tipo:this.getTipoUsuario ()]	
	}
	
	def search_advanced ={
		return [tipo:this.getTipoUsuario ()]
	}
	
	def results ={
		if (!params.max) params.max = 50
		if (!params.offset) params.offset = 0
		if (!params.sort) params.sort = "titulo"
		if (!params.order) params.order = "asc"
		
		consulta = params
		
		def criteria = Livro.createCriteria()
		
		livroResult = criteria {
			maxResults(params.max?.toInteger())
			firstResult(params.offset?.toInteger())
			order(params.sort, params.order)
			and{ like('titulo','%' + params.titulo + '%') }
		}
		
		[pesquisaLivro: livroResult,params : params, tipo:this.getTipoUsuario ()]
	}
	
	def results_livros ={
		if (!params.max) params.max = 50
		if (!params.offset) params.offset = 0
		if (!params.sort) params.sort = "titulo"
		if (!params.order) params.order = "asc"
		
		consulta = params
		
		def criteria = Livro.createCriteria()
		
		livroResult = criteria {
			maxResults(params.max?.toInteger())
			firstResult(params.offset?.toInteger())
			order(params.sort, params.order)
			and{
				like('titulo','%' + params.titulo + '%')
				like('autores','%' + params.autores + '%')
				like('editora','%' + params.editora + '%')							
				
				like('ano','%' +  params.ano + '%')		
				
				like('isbn', '%' + params.isbn + '%')								                   
			}
		}
		
		[pesquisaLivro: livroResult,params : params, tipo:this.getTipoUsuario ()]
	}
	
	
	def save = {
		def livroInstance = new Livro(params)
		def exemplarInstance = new Exemplar(dataDeAquisicao: new Date(), livro: params.titulo, isbnItem: params.isbn)
		if (params.fornecedor[0].toString().equals("Novo Fornecedor")){
			exemplarInstance.fornecedor = params.fornecedor[1].toString()
			params.fornecedor = params.fornecedor[1]
			livroInstance.fornecedor = params.fornecedor
			if (exemplarInstance.fornecedor.equals ('')){
				livroInstance.fornecedor = null
				params.fornecedor = ''
			}
		}else {
			exemplarInstance.fornecedor = params.fornecedor[0].toString()
			livroInstance.fornecedor = params.fornecedor[0].toString()
		}
		
		livroInstance.isbn = params.isbn.toString()
		if (livroInstance.save(flush: true)) {
			exemplarInstance.save()
			flash.message = "${message(code: 'default.created.message', args: [message(code: 'livro.label', default: 'Livro'), livroInstance.id])}"
			redirect(action: "show", id: livroInstance.id)
		}
		else {
			if (!fornecedores.contains('Doacao')){
				fornecedores.add('Doacao')
			}
			render(view: "create", model: [livroInstance: livroInstance, fornecedores:fornecedores, tipo:this.getTipoUsuario ()])
		}
	}
	
	def show = {
		def livroInstance = Livro.get(params.id)
		def qtde = Exemplar.executeQuery("select id from Exemplar where isbnItem = '" + livroInstance.isbn + "'")
		def emprestados = Emprestimo.executeQuery("select id from Emprestimo where idItem = " + livroInstance.id +" and tipo = 'livro'")
		def reservados = Reserva.executeQuery("select id from Reserva where idItem = " + livroInstance.id)
		
		if (!livroInstance) {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'livro.label', default: 'Livro'), params.id])}"
			redirect(action: "list")
		}
		else {
			[livroInstance: livroInstance, qtde:qtde.size(), disponiveis:qtde.size() - emprestados.size() - reservados.size(), reservados:reservados.size(), emprestados:emprestados.size(), tipo:this.getTipoUsuario (), username:username]
		}
	}
	
	def edit = {
		def livroInstance = Livro.get(params.id)
		if (!livroInstance) {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'livro.label', default: 'Livro'), params.id])}"
			redirect(action: "list")
		}
		else {
			if (!fornecedores.contains('Doacao')){
				fornecedores.add('Doacao')
			}
			return [livroInstance: livroInstance, fornecedores:fornecedores, tipo:this.getTipoUsuario ()]
		}
	}
	
	def update = {
		def livroInstance = Livro.get(params.id)
		if (livroInstance) {
			if (params.version) {
				def version = params.version.toLong()
				if (livroInstance.version > version) {
					
					livroInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'livro.label', default: 'Livro')] as Object[], "Another user has updated this Livro while you were editing")
					render(view: "edit", model: [livroInstance: livroInstance])
					return
				}
			}
			livroInstance.properties = params
			
			if (!livroInstance.hasErrors() && livroInstance.save(flush: true)) {
				flash.message = "${message(code: 'default.updated.message', args: [message(code: 'livro.label', default: 'Livro'), livroInstance.id])}"
				redirect(action: "show", id: livroInstance.id)
			}
			else {
				if (!fornecedores.contains('Doacao')){
					fornecedores.add('Doacao')
				}
				render(view: "edit", model: [livroInstance: livroInstance, fornecedores:fornecedores, tipo:this.getTipoUsuario ()])
			}
		}
		else {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'livro.label', default: 'Livro'), params.id])}"
			redirect(action: "list")
		}
	}
	
	def delete = {
		def livroInstance = Livro.get(params.id)
		if (livroInstance) {
			try {
				livroInstance.delete(flush: true)
				flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'livro.label', default: 'Livro'), params.id])}"
				redirect(action: "list")
			}
			catch (org.springframework.dao.DataIntegrityViolationException e) {
				flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'livro.label', default: 'Livro'), params.id])}"
				redirect(action: "show", id: params.id)
			}
		}
		else {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'livro.label', default: 'Livro'), params.id])}"
			redirect(action: "list")
		}
	}
	
	def createReportLivroSimple = {
		def livros = livroResult		
		
		String caminhoLogoSPL = System.getProperty("user.dir") + "\\web-app\\reports\\logo_spl_report.jpg";
		String caminhoLogoGMF = System.getProperty("user.dir") + "\\web-app\\reports\\gmf.jpg";
		
		params.put("logoSPL", caminhoLogoSPL);
		params.put("logoGMF", caminhoLogoGMF);
		params.put("tituloConsulta", consulta.titulo);
		
		
		chain(controller:'jasper',action:'index',model:[data:livros],params:params)
	}
	
	def createReportLivroComplete = {
		def livros = livroResult
		
		String caminhoLogoSPL = System.getProperty("user.dir") + "\\web-app\\reports\\logo_spl_report.jpg";
		String caminhoLogoGMF = System.getProperty("user.dir") + "\\web-app\\reports\\gmf.jpg";
		
		params.put("logoSPL", caminhoLogoSPL);
		params.put("logoGMF", caminhoLogoGMF);
		params.put("tituloConsulta", consulta.titulo);
		
		params.put("autoresConsulta", consulta.autores);
		params.put("anoConsulta", consulta.ano);
		params.put("isbnConsulta", consulta.isbn);
		params.put("editoraConsulta", consulta.editora);
		params.put("fornecedorConsulta", consulta.fornecedor);
		
		
		chain(controller:'jasper',action:'index',model:[data:livros],params:params)
	}
}
